<?php


namespace App\Imports;

use App\Exceptions\ApiException;
use App\Services\CommonService;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithColumnLimit;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithStartRow;

/**
 * Class BookTitleImport
 * @package App\Imports
 * 适用于 29号文件
 */
class DocArchiveImport implements ToModel, WithChunkReading, WithStartRow, WithColumnLimit, WithBatchInserts, WithLimit, SkipsEmptyRows
{
    protected $chunkSize;
    protected $startRow;
    protected $endColumn;
    protected $batchSize;
    protected $tmpKey;

    public function __construct($importCountKey)
    {
        $this->limit             = 10000; //只读取前10000行
        $this->chunkSize         = 100;  //将数据拆成小块读取
        $this->startRow          = 1;    //从第几行开始
        $this->endColumn         = 'H';  //指定到那一列为止
        $this->batchSize         = 100;  //批量写入的数据大小
        $this->docArchiveInfoKey = 'import_doc_archive';
        $this->importCountKey    = $importCountKey;
        $this->tmpKey            = 'data';
    }

    /**
     * 导入数据
     */
    public function model(array $row)
    {
        if (trim($row[0]) == '年度：') {
            self::cacheInfo($row); //把头部信息缓存起来
        } elseif (trim($row[0] != '盒号')) {
            $docArchiveInstance = CommonService::getDocArchiveInstance();
            $cacheInfo = redis()->get($this->docArchiveInfoKey);
            $cacheInfo = json_decode($cacheInfo, true);
            $project   = format_table_label($cacheInfo[4]);
            $docArchiveInstance->updateOrCreate(
                [ //查询条件
                    'company_id'   => company_id(),
                    'project'      => substr($project, 0, strpos($project, '归档文件目录')),//项目
                    'year'         => format_table_label($cacheInfo[1]),    //年份
                    'agency'       => substr(format_str($cacheInfo[2]), 9), //机构
                    'store_period' => format_table_label($cacheInfo[7]),    //保管期限
                    'box_num'      => format_table_label($row[0]),          //盒号
                    'piece_num'    => format_table_label($row[1]),          //件号
                    'file_num'     => format_table_label($row[3]),          //文号
                ],
                [ //数据
                    'director'   => format_table_label($row[2]), //责任者
                    'file_num'   => format_table_label($row[3]), //文号
                    'title'      => format_table_label($row[4]), //案卷题名
                    'c_date'     => format_table_label($row[5]), //日期
                    'page_num'   => format_table_label($row[6]), //页数
                    'remark'     => format_table_label($row[7]), //备注
                    'created_at' => now(),
                    'updated_at' => now(),
                    'creator_id' => user_id(),
                ]);
            redis()->incr($this->importCountKey); //导入的数据量加
        }
    }

    /**
     * 使用档案号查询案卷目录id，查出后进行缓存
     */
    private function cacheInfo($row)
    {
        $info = json_encode($row);
        redis()->setex($this->docArchiveInfoKey, 60, $info); //把档案号存起来
    }

    /**
     * 检查格式是否正确，判断列的属性汉字
     * @author: lxk
     * @date: 2023/6/3 15:18
     */
    public function checkFormat($row)
    {
        if (format_table_label($row[0]) == '盒号') {
            if (format_table_label($row[1]) != '件号'
                || format_table_label($row[2]) != '责任者'
                || format_table_label($row[3]) != '文号'
                || format_table_label($row[4]) != '题名'
                || format_table_label($row[5]) != '日期'
                || format_table_label($row[6]) != '页数'
                || format_table_label($row[7]) != '备注'
            ) {
                throw new ApiException("案卷格式错误！列属性名必须和模板完全一致，请下载模板，核对数据列【A~I】");
            }
        }


    }

    /**
     * 将数据拆成小块进行导入，减小内存占用
     *
     * @return int
     */
    public function chunkSize(): int
    {
        return $this->chunkSize;
    }

    /**
     * 直接过滤表头，第一块数据含表头
     *
     * @return int
     */
    public function startRow(): int
    {
        return $this->startRow;
    }

    /**
     * 指定到那一列为止，G代表读取到G列就不再读取
     *
     * @return string
     */
    public function endColumn(): string
    {
        return $this->endColumn;
    }

    /**
     * 批量写入的数据大小
     *
     * @return int
     */
    public function batchSize(): int
    {
        return $this->batchSize;
    }

    public function limit(): int
    {
        return $this->limit;
    }

}
